from scapy.all import ARP, Ether, srp
import time
import json
import os

# 配置
INTERFACE = None          # 使用默认网卡，可指定如 'wlan0'
ARP_TIMEOUT = 3           # ARP 请求超时时间
SCAN_INTERVAL = 60        # 每60秒扫描一次（生产环境可调整）
HISTORY_FILE = "arp_history.json"

def get_network_range():
    """简单获取本地网络段（如 192.168.1.0/24），可根据实际环境优化"""
    # 这里简化处理，实际可用 netifaces 或 ip route 获取
    return "192.168.1.0/24"

def scan_devices(network):
    """扫描局域网内活跃设备"""
    arp = ARP(pdst=network)
    ether = Ether(dst="ff:ff:ff:ff:ff:ff")
    packet = ether / arp
    result = srp(packet, timeout=ARP_TIMEOUT, iface=INTERFACE, verbose=False)[0]

    devices = {}
    for sent, received in result:
        ip = received.psrc
        mac = received.hwsrc.upper()  # 标准化 MAC
        devices[mac] = {'ip': ip, 'last_seen': time.time()}
    return devices

def load_history():
    """加载历史设备记录"""
    if os.path.exists(HISTORY_FILE):
        with open(HISTORY_FILE, 'r') as f:
            return json.load(f)
    return {}

def save_history(history):
    """保存设备历史"""
    with open(HISTORY_FILE, 'w') as f:
        json.dump(history, f, indent=2)

def check_new_devices(current_devices, history):
    """检查新设备"""
    new_devices = {}
    for mac, info in current_devices.items():
        if mac not in history:
            print(f"🚨 新设备接入: MAC={mac}, IP={info['ip']}")
            new_devices[mac] = info
        else:
            # 更新最后出现时间
            history[mac]['last_seen'] = info['last_seen']
    return new_devices

def main():
    print("开始监控 Wi-Fi 网络设备...")
    network = get_network_range()
    print(f"监控网段: {network}")

    while True:
        try:
            current = scan_devices(network)
            history = load_history()

            new_devices = check_new_devices(current, history)

            # 将新设备加入历史记录
            for mac, info in current.items():
                if mac not in history:
                    history[mac] = info

            save_history(history)
            print(f"当前活跃设备: {len(current)} 台")

            time.sleep(SCAN_INTERVAL)

        except KeyboardInterrupt:
            print("\n监控结束。")
            break
        except Exception as e:
            print(f"扫描出错: {e}")
            time.sleep(10)

if __name__ == "__main__":
    main()